﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class BezierSpline : MonoBehaviour
{
    public List<BezierControlPoint> controlPoints = new List<BezierControlPoint>();
    public bool loop;
    private Transform m_tsm;

    public void AddPoint()
    {
        BezierControlPoint point = this.controlPoints.LastOrDefault<BezierControlPoint>();
        BezierControlPoint item = new BezierControlPoint(Vector3.zero);
        if (point != null)
        {
            item.mode = point.mode;
            item.position = point.position + Vector3.right;
        }
        this.controlPoints.Add(item);
    }

    public void DrawDebugLine()
    {
        for (float i = 0f; i < 1f; i += 0.005f)
        {
            Debug.DrawLine(this.Evaluate(i), this.Evaluate(i + 0.005f), (Color) (Color.white * 0.5f));
        }
    }

    public Vector3 Evaluate(float t)
    {
        if (this.controlPoints.Count == 0)
        {
            return Vector3.zero;
        }
        if (this.controlPoints.Count == 1)
        {
            return this.controlPoints[0].position;
        }
        int num = this.controlPoints.Count - 1;
        if (this.loop)
        {
            num++;
        }
        float num2 = num * 1f;
        float num3 = num2 / ((float) num);
        t = Mathf.Clamp01(t);
        int num4 = (int) (num2 * t);
        num4 = Mathf.Clamp(num4, 0, this.controlPoints.Count - 1);
        float num5 = (num2 * t) - (num3 * num4);
        Vector3 position = this.controlPoints[num4].Evaluate(this.GetPrev(num4), this.GetNext(num4), num5);
        return this.tsm.TransformPoint(position);
    }

    public void EvaluateAll(float subdivision, ref Vector3[] container)
    {
        int newSize = 0;
        for (int i = 0; i < this.controlPoints.Count; i++)
        {
            BezierControlPoint point = this.controlPoints[i];
            BezierControlPoint prev = this.GetPrev(i);
            BezierControlPoint next = this.GetNext(i);
            Vector3 vector2 = next.position - point.position;
            float magnitude = vector2.magnitude;
            for (float j = 0f; j < 1f; j += (1f / subdivision) / magnitude)
            {
                Vector3 vector = this.controlPoints[i].Evaluate(prev, next, j);
                newSize++;
                if (container.Length < newSize)
                {
                    Array.Resize<Vector3>(ref container, newSize);
                }
                container[newSize - 1] = vector;
            }
        }
        if (container.Length > newSize)
        {
            Array.Resize<Vector3>(ref container, newSize);
        }
    }

    public Vector3 EvaluateNormal(float t)
    {
        if (t == 1f)
        {
            t -= 0.01f;
        }
        Vector3 vector = this.Evaluate(t);
        Vector3 vector3 = this.Evaluate(t + 0.01f) - vector;
        return vector3.normalized;
    }

    public BezierControlPoint GetNext(int index)
    {
        int num = !this.loop ? Mathf.Clamp(index + 1, 0, this.controlPoints.Count - 1) : ((int) Mathf.Repeat((float) (index + 1), (float) this.controlPoints.Count));
        return this.controlPoints[num];
    }

    public BezierControlPoint GetPrev(int index)
    {
        int num = !this.loop ? Mathf.Clamp(index - 1, 0, this.controlPoints.Count - 1) : ((int) Mathf.Repeat((float) (index - 1), (float) this.controlPoints.Count));
        return this.controlPoints[num];
    }

    public void InsertPoint(int index, Vector3 position)
    {
        this.controlPoints.Insert(index, new BezierControlPoint(position));
    }

    private void OnDrawGizmos()
    {
        this.DrawDebugLine();
    }

    public void RemovePoint(int index)
    {
        this.controlPoints.RemoveAt(index);
    }

    public void SetAllPointMode(BezierControlPointMode mode)
    {
        foreach (BezierControlPoint point in this.controlPoints)
        {
            point.mode = mode;
        }
    }

    public Transform tsm
    {
        get
        {
            return ((this.m_tsm != null) ? this.m_tsm : (this.m_tsm = base.transform));
        }
    }
}

